<?php
//@version: $Id: checkFileBom_cli.php 175 2011-03-30 12:51:52Z horseluke@126.com $
//增强版的，仅能运行在cli模式下的检查utf-8文件bom签名脚本
//本文件仅允许使用命令行模式运行！字符型参数请使用""包含：
//php -f "checkFileBom_cli.php" "要检测的dir" 0 0 "log文件和路径，比如x:/xxxx.log"
//第一个0也可以是1，表示自动移除发现的BOM信息；第二个0也可以是1，表示将检查全过程也打印在CLI下
set_time_limit(0);

//设置默认值
$basedir = "."; //修改此行为需要检测的目录，点表示当前目录
$auto = 0; //是否自动移除发现的BOM信息。1为是，0为否。
$showProcess = 0;  //是否将检查全过程也打印出来？默认为否
$logFile = '';  //log文件和路径，比如x:/xxxx.log
$extAllow = array('php', 'html', 'htm');  //要检测的文件名后缀

//以下不用改动
if(!function_exists('file_put_contents')){
	trigger_error('function file_put_contents doesn\'t exist! PHP_VERSION:'. PHP_VERSION, E_USER_ERROR);
}

//命令行模式传值
if(isset($argv[1])){
	$basedir = $argv[1];
}else{
	trigger_error('PLEASE SET THE DIRECTORY IN CLI MODE!', E_USER_ERROR);
}
if(isset($argv[2]) && $argv[2] == 1){
	$auto = 1;
}
if(isset($argv[3]) && $argv[3] == 1){
	$showProcess = 1;
}
if(isset($argv[4])){
	$logFile = $argv[4];
}

$logresult = array();
runCheckBom($basedir);
logResult();
echo "\n===FINISH===";


function runCheckBom($basedir)
{
	if(!is_dir($basedir)){
		trigger_error($basedir. ' is not a directory!', E_USER_ERROR);
	}
	
	if ($dh = opendir($basedir)){
		while (($file = readdir($dh)) !== false){
			if ($file!='.' && $file!='..' && $file != '.svn') {   //svn目录不检查
				if (is_dir($basedir."/".$file)){
					runCheckBom($basedir."/".$file);
				}else{
					checkBOM("$basedir/$file");
				}
			} 
		}
		closedir($dh);
	}else{
		trigger_error('Can not open dir: '. $basedir, E_USER_WARNING);
	}
}


function checkBOM ($filename) {
	global $auto, $extAllow, $logresult, $showProcess;
	
	$tmpAry = explode('.', $filename);
	$ext 	= array_pop( $tmpAry );
	if (in_array(strtolower($ext), $extAllow)){
		
		$size = filesize($filename);
		if(false == $size || $size == 0 || $size > 1024 * 1024){ //大于1M的不检查
			$showProcess && showOneResult('FILESIZE CAN NOT REACH NOR TOO BIG NOR IS ZERO'. "\t". $filename);
			return -1;
		}
		
		$contents = file_get_contents($filename);
		if(!$contents){
			$showProcess && showOneResult('CONTENT GET FAIL'. "\t". $filename);
			return -2;
		}
		$charset = array();
		/*
		$charset[1]=substr($contents, 0, 1);
		$charset[2]=substr($contents, 1, 1);
		$charset[3]=substr($contents, 2, 1);
		*/
		$charset[1] = $contents[0];
		$charset[2] = isset($contents[1]) ? $contents[1] : '';
		$charset[3] = isset($contents[2]) ? $contents[2] : '';
		
		if (ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191) {
			$echoString = 'FOUND UTF8-BOM'. "\t". $filename;
			if ($auto == 1) {
				$contents=substr($contents, 3);
				rewrite($filename, $contents);
				$echoString .= "\t". 'CLEAN SUCCESS';
				showOneResult($echoString, true);
				return 1;
			} else {
				showOneResult($echoString, true);
				return 2;
			}
		}else{
			$showProcess && showOneResult('NOT FOUND UTF8-BOM'. "\t". $filename);
			return 0;
		}
	}else{
		$showProcess && showOneResult('FILE EXT NOT MATCH'. "\t". $filename);
		return -3;
	}

}

function rewrite($filename, $data) {
	$filenum=fopen($filename,"wb");
	flock($filenum,LOCK_EX);
	fwrite($filenum,$data);
	fclose($filenum);
}


function showOneResult($string, $log = false){
	global $logresult;
	echo $string. "\n";
	if($log == true){
		$logresult[] = $string;
		if(count($logresult) >= 50){
			logResult();
		}
	}
}


function logResult(){
	global $logFile,$logresult;
	if(!empty($logresult) && !empty($logFile)){
		$data = implode("\n\r",$logresult). "\n\r";
		file_put_contents($logFile, $data, FILE_APPEND);
	}
	$logresult = array();
}

